home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume15 / yp-quote < prev   
Encoding:
Text File  |  1988-06-07  |  18.5 KB  |  674 lines

  1. Newsgroups: comp.sources.unix
  2. Subject: v15i048:  Building custom Yellow Page Maps
  3. Approved: rsalz@uunet.UU.NET
  4.  
  5. Submitted-by: Chuq Von Rospach <chuq@sun.com>
  6. Posting-number: Volume 15, Issue 48
  7. Archive-name: yp-quote
  8.  
  9. [  It came in two pieces, so I repacked it. --r$ ]
  10. This toy application creates a map called 'quotes'. The program 'quote'
  11. will then access a random data element of this map and print it out.
  12. The source I've used for the data of quotes is the fortune data file,
  13. so this is essentially a Yellow Page based, distributed version of the
  14. fortune program.
  15.  
  16. See the README for more details. This code is completely
  17. non-proprietary and was written using nothing more than my background
  18. in this stuff, the documentation and man pages. So it's completely
  19. non-proprietary and unrestricted. Feel free to pass it around as widely
  20. as you want -- it was written to teach me how to do this, and I make it
  21. available to help teach you.
  22.  
  23. Have fun! comments, etc. to me!
  24.  
  25. chuq, Sun Tech Support
  26. --------------------------------------
  27. #! /bin/sh
  28. # This is a shell archive.  Remove anything before this line, then unpack
  29. # it by saving it into a file and typing "sh file".  To overwrite existing
  30. # files, type "sh file -c".  You can also feed this as standard input via
  31. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  32. # will see the following message at the end:
  33. #        "End of archive 1 (of 1)."
  34. # Contents:  Makefile README addpct.c quote.c quote.l quotedb.c
  35. #   strfile.h unstr.c
  36. # Wrapped by rsalz@fig.bbn.com on Wed Jun  8 15:36:35 1988
  37. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  38. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  39.   echo shar: Will not clobber existing file \"'Makefile'\"
  40. else
  41. echo shar: Extracting \"'Makefile'\" \(356 characters\)
  42. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  43. X#
  44. X# Makefile for quotedb
  45. X#
  46. XCFLAGS= -g
  47. X
  48. Xall: addpct quote quotedb unstr
  49. X
  50. Xclean: 
  51. X    rm -f addpct quote quotedb unstr core *.o
  52. X
  53. Xaddpct: addpct.o
  54. X    $(CC) $(CFLAGS) addpct.o -o addpct
  55. X
  56. Xquote: quote.o
  57. X    $(CC) $(CFLAGS) quote.o -o quote
  58. X
  59. Xquotedb: quotedb.o
  60. X    $(CC) $(CFLAGS) quotedb.o -o quotedb
  61. X
  62. Xunstr: unstr.o
  63. X    $(CC) $(CFLAGS) unstr.o -o unstr
  64. X
  65. Xunstr.o: strfile.h 
  66. END_OF_FILE
  67. if test 356 -ne `wc -c <'Makefile'`; then
  68.     echo shar: \"'Makefile'\" unpacked with wrong size!
  69. fi
  70. # end of 'Makefile'
  71. fi
  72. if test -f 'README' -a "${1}" != "-c" ; then 
  73.   echo shar: Will not clobber existing file \"'README'\"
  74. else
  75. echo shar: Extracting \"'README'\" \(4755 characters\)
  76. sed "s/^X//" >'README' <<'END_OF_FILE'
  77. XDocumentation for the quote program, a toy application showing how to
  78. Xset up and use a custom Yellow Pages database.
  79. X
  80. XChuq Von Rospach
  81. XSun Tech Support
  82. X
  83. XRelease 1.0: May 2, 1988
  84. X                                   
  85. X                              Manifest:
  86. X
  87. XMakefile
  88. X    Builds everything of interest
  89. XREADME
  90. X    This file
  91. Xaddpct.c
  92. X    Takes a file of quotes separated by blank lines and converts
  93. X    them into the fortune file format separated by a line containing
  94. X    '%%' -- used to convert Moriarty quotes to fortune quotes (and
  95. X    if you don't know what that means, ignore this)
  96. Xquote.c
  97. X    The user program. Looks up random quotes from the quotes Yellow
  98. X    Pages database.
  99. Xquotedb.c
  100. X    This program reads a fortune source file and puts it into a format
  101. X    usable by makedbm to create a Yellow Pages map.
  102. Xstrfile.h
  103. Xunstr.c
  104. X    These public domain programs by Ken Arnold read a compiled fortune
  105. X    file (for instance, /usr/games/lib/fortunes.dat) and turn it into
  106. X    a source file readable by man or the quotedb program.
  107. X
  108. X                         What this stuff is:
  109. X
  110. XThe quote program is a toy application designed to show how to implement
  111. Xyour own custom Yellow Pages maps under SunOS 3.x or 4.0. YP maps are a
  112. Xgood, general purpose distributed database. Because of a dearth of good
  113. Xdocumentation on it, few customer databases have been developed for it. This
  114. Xprogram is aimed at clearing up some of the confusion of how to generate
  115. Xmaps and then access the data in them.
  116. X
  117. XYellow Page maps are created by the "makedbm" program. The format of the
  118. Xthe input data is simple, consisting of a key and data:
  119. X
  120. X    key<whitespace>data<newline>
  121. X
  122. XOnce data is in the map, it can then be pulled out by doing a lookup on the
  123. Xgiven key. At the user level, that is done by:
  124. X
  125. X    ypmatch key mapname
  126. X
  127. Xquote.c shows how to do it from a programmatic view.
  128. X
  129. XHow to Set this up:
  130. X
  131. X    o Compile unstr.c
  132. X    o use unstr.c to de-compile /usr/games/lib/fortunes.dat (note:
  133. X        this requires root, as does all the YP stuff....)
  134. X    o cp the created file to /var/yp/quotes (/usr/etc/yp/quotes
  135. X        under 3.X)
  136. X    o compile quotedb.c, and copy it into /var/yp/quotedb
  137. X    o Add the following rule to /var/yp/Makefile (this will require
  138. X        minor changes, mostly pathnames, to go into 
  139. X        /usr/etc/yp/Makefile. Changes should be obvious
  140. X        in context of the existing YP Makefile)
  141. X
  142. X--------- /var/yp/Makefile ---------------
  143. X# Add quotes to the all rule
  144. Xall: passwd group hosts ethers networks rpc services protocols \
  145. X    netgroup bootparams aliases publickey netid c2secure netmasks \
  146. X    stars ypservers quotes
  147. X
  148. Xquotes.time: $(YPDBDIR)/quotes
  149. X    -@if [ -f $(YPDBDIR)/quotes ]; then \
  150. X        quotedb < $(YPDBDIR)/quotes | $(MAKEDBM) - \
  151. X                    $(YPDBDIR)/$(DOM)/quotes; \
  152. X        touch quotes.time; \
  153. X        echo "update quotes"; \
  154. X        if [ ! $(NOPUSH) ]; then \
  155. X            $(YPPUSH) quotes; \
  156. X            echo "pushed quotes"; \
  157. X        else \
  158. X            : ; \
  159. X        fi \
  160. X    else \
  161. X        echo "couldn't find $(YPDBDIR)/quotes"; \
  162. X    fi
  163. X
  164. X# Add to the dependency list
  165. Xquotes: quotes.time
  166. X
  167. X-------- end /var/yp/Makefile -----------
  168. X
  169. X    o cd into /var/yp and run 'make'
  170. X    o if all goes well, the map should exist. "ypwhich -m" should say
  171. X        something like:
  172. X            quotes plaid # replace plaid with your yp server name
  173. X        "ypmatch MAX quotes" should print out a number, and
  174. X        "ypmatch 15 quotes" should print out a quote.
  175. X
  176. X    o compile quote.c. Try running quote. It should print a quote.
  177. X                                   
  178. X                           Final Comments:
  179. X
  180. XNote that quote doesn't support any of the flags that the fortune program
  181. Xhas, such as long, short, obscene, etc. Other than that, this makes a good
  182. Xreplacement for keeping /usr/games on the disk or NFS mounting /usr/games
  183. Xif all you care about is running fortune when you log in. 
  184. X
  185. XPlease note that the program unstr is a public domain program written by Ken
  186. XArnold to unpack the public domain fortune's data files. This format happens
  187. Xto also work with the SunOS fortune files (not surprising, since Ken wrote
  188. Xthe original fortune, which we've adopted).
  189. X
  190. XAlso, all of this code was written from the man pages and documentation, not
  191. Xfrom any proprietary source. It is, therefore, not proprietary to either Sun
  192. Xor AT&T source code agreements, so you can pass it around as widely as you
  193. Xwant. That's the point, of course -- this is designed to be educational.
  194. X
  195. XNote that because of inherent (but very large) limitations of the ndbm()
  196. Xpackage, it is possible to build a data set too large for YP to handle.
  197. XIf you get that, you'll see errors from makedbm and the map won't create
  198. Xor update. All you can do is make the dataset smaller. The only place I've
  199. Xseen this is with my special, 6000 entry quote file, but you've been warned.
  200. XAnd no, I don't distribute my quote file -- it's too large.
  201. X
  202. Xcomments, thoughts, feedback, criticism and money are all welcome. 
  203. END_OF_FILE
  204. if test 4755 -ne `wc -c <'README'`; then
  205.     echo shar: \"'README'\" unpacked with wrong size!
  206. fi
  207. # end of 'README'
  208. fi
  209. if test -f 'addpct.c' -a "${1}" != "-c" ; then 
  210.   echo shar: Will not clobber existing file \"'addpct.c'\"
  211. else
  212. echo shar: Extracting \"'addpct.c'\" \(356 characters\)
  213. sed "s/^X//" >'addpct.c' <<'END_OF_FILE'
  214. X/*
  215. X * This takes a file with quotes delimited by a blank line (typically
  216. X * a moriarty quote file) and turns it into a %% delimited file that
  217. X * can be imported into a fortune database
  218. X *
  219. X * chuq von rospach
  220. X */
  221. X
  222. X#include <stdio.h>
  223. X
  224. Xmain()
  225. X{
  226. X    char line[BUFSIZ];
  227. X
  228. X    while (gets(line))
  229. X    if (strlen(line))
  230. X        puts(line);
  231. X    else
  232. X        printf("%%%%\n");
  233. X}
  234. END_OF_FILE
  235. if test 356 -ne `wc -c <'addpct.c'`; then
  236.     echo shar: \"'addpct.c'\" unpacked with wrong size!
  237. fi
  238. # end of 'addpct.c'
  239. fi
  240. if test -f 'quote.c' -a "${1}" != "-c" ; then 
  241.   echo shar: Will not clobber existing file \"'quote.c'\"
  242. else
  243. echo shar: Extracting \"'quote.c'\" \(1520 characters\)
  244. sed "s/^X//" >'quote.c' <<'END_OF_FILE'
  245. X#include <stdio.h>
  246. X#include <rpcsvc/ypclnt.h>
  247. X
  248. X#define MAXLEN 4096
  249. X#define randint(maxval) ((random() % (maxval)) + 1)
  250. X
  251. Xchar dom_name[BUFSIZ];
  252. X
  253. Xmain()
  254. X{
  255. X    char *quotebuf;
  256. X    int quotelen;
  257. X    char *maxbuf;
  258. X    int maxlen;
  259. X    int maxnum = 0;
  260. X    int quotenum = 0;
  261. X    char *c;
  262. X    char *index();
  263. X
  264. X    srandom(getpid()); /* initialize random numbers */
  265. X
  266. X    /* who are we? */
  267. X    if (getdomainname(dom_name, BUFSIZ)) {
  268. X    fprintf(stderr, "No domainname set\n");
  269. X    exit(1);
  270. X    }
  271. X
  272. X    /* Get the highest quote in the system */
  273. X    get_match("MAX", &maxbuf, &maxlen);
  274. X    maxnum = atoi(maxbuf);
  275. X
  276. X    /* Generate a random number between 1 and maxnum */
  277. X    quotenum = randint(maxnum);
  278. X    if (quotenum < 0 || quotenum > maxnum) {
  279. X    fprintf(stderr, "Illegal randint value!\n");
  280. X    exit(1);
  281. X    }
  282. X
  283. X    /* now grab that quote */
  284. X    sprintf(maxbuf,"%d",quotenum);
  285. X    get_match(maxbuf, "ebuf, "elen);
  286. X
  287. X    /* turn all ^A characters to newlines.
  288. X     * turn all ^B characters to tabs.
  289. X     * needed to allow proper insertion into a yp database, since makedbm
  290. X     * uses both as delimiters.
  291. X     */
  292. X    while ((c = index(quotebuf,'\001')))
  293. X    *c = '\n';
  294. X
  295. X    while ((c = index(quotebuf,'\002')))
  296. X    *c = '\t';
  297. X    
  298. X    /* print it out */
  299. X    printf("%s",quotebuf);
  300. X}
  301. X
  302. X/* get the largest quote from key MAX */
  303. X
  304. Xget_match(key, retval, retlen)
  305. X    char *key;
  306. X    char **retval;
  307. X    int *retlen;
  308. X{
  309. X
  310. X    if (yp_match(dom_name, "quotes", key, strlen(key), retval, retlen)) {
  311. X    fprintf(stderr, "error in ypmatch\n");
  312. X    exit(1);
  313. X    }
  314. X}
  315. END_OF_FILE
  316. if test 1520 -ne `wc -c <'quote.c'`; then
  317.     echo shar: \"'quote.c'\" unpacked with wrong size!
  318. fi
  319. # end of 'quote.c'
  320. fi
  321. if test -f 'quote.l' -a "${1}" != "-c" ; then 
  322.   echo shar: Will not clobber existing file \"'quote.l'\"
  323. else
  324. echo shar: Extracting \"'quote.l'\" \(1457 characters\)
  325. sed "s/^X//" >'quote.l' <<'END_OF_FILE'
  326. X.TH QUOTE 6
  327. X.SH NAME
  328. Xquote - read quotes from a Yellow Pages Database
  329. X.SH SYNOPSIS
  330. X.B quote
  331. X.br
  332. X.B quotedb
  333. X.SH DESCRIPTION
  334. X.I Quote
  335. Xis a toy application designed to show how to create and access a custom
  336. XYellow Pages database.
  337. XIt creates a Yellow Pages version of the program
  338. Xfortune.
  339. X.PP
  340. X.I Quote
  341. Xis the user program.
  342. XIt reads the Yellow Pages database "quotes" to get a random quote
  343. Xout of it.
  344. X.PP
  345. X.I Quotedb
  346. Xis the program that takes a "fortune" style source file and turns it into
  347. Xa format that can be fed to 
  348. X.I makedbm
  349. Xto create the Yellow Pages database.
  350. X.PP
  351. XSee the README and the source for the grotty details of how to modify the
  352. XYP Makefile and how all this stuff fits together.
  353. X.SH AUTHOR
  354. XChuq Von Rospach, Sun Microsystems Tech Support (chuq@sun.COM)
  355. X.SH DIAGNOSTICS
  356. XGenerally self-documenting, as they say. At least in theory.
  357. X.PP
  358. XError messages from 
  359. X.I makedbm
  360. Xmay not be as clear as you might hope.
  361. X.SH BUGS
  362. XThere are limits to the amount of data that can be shoved in a ndbm(3)
  363. Xdatabase.
  364. XLarge text based items (like quotes) will fill up a database faster than
  365. Xsmall ones.
  366. XSince YP uses ndbm(3) for internal storage, this means you might
  367. Xget creation errors on very large fortune files.
  368. XIf you get them, all you can do is shrink the data-set. In all practical
  369. Xcases,
  370. Xthis is probably not a problem.
  371. XI had to build an extremely large quotes file to find this out (the hard
  372. Xway, of course).
  373. XThanks to moriarty for making this bug findable.
  374. X
  375. END_OF_FILE
  376. if test 1457 -ne `wc -c <'quote.l'`; then
  377.     echo shar: \"'quote.l'\" unpacked with wrong size!
  378. fi
  379. # end of 'quote.l'
  380. fi
  381. if test -f 'quotedb.c' -a "${1}" != "-c" ; then 
  382.   echo shar: Will not clobber existing file \"'quotedb.c'\"
  383. else
  384. echo shar: Extracting \"'quotedb.c'\" \(878 characters\)
  385. sed "s/^X//" >'quotedb.c' <<'END_OF_FILE'
  386. X#include <stdio.h>
  387. X
  388. X#define MAXLEN 450
  389. X
  390. Xchar quotebuf[MAXLEN];
  391. Xchar line[MAXLEN];
  392. Xint numq = 0;
  393. X
  394. Xchar *strcat();
  395. Xchar *strcpy();
  396. X
  397. Xmain()
  398. X{
  399. X
  400. X    char *c, *index();
  401. X    int endit = 0;
  402. X
  403. X    while (gets(line)) {
  404. X    if (line[0] == '%' && (line[1] == '%' || line[1] == '-')) {
  405. X
  406. X        if (strlen(quotebuf)) {
  407. X        numq++;
  408. X
  409. X        /*
  410. X         * mark all newlines and tabs with special character flags so
  411. X         * you don't confuse makedbm
  412. X         */
  413. X
  414. X        while ((c = index(quotebuf, '\n')))
  415. X            *c = '\001';
  416. X
  417. X        while ((c = index(quotebuf, '\t')))
  418. X            *c = '\002';
  419. X
  420. X        printf("%d\t%s\n", numq, quotebuf);
  421. X        strcpy(quotebuf, "");
  422. X        }
  423. X    } else {
  424. X
  425. X        if ((strlen(line) + strlen(quotebuf)) > MAXLEN) {
  426. X/*        fprintf(stderr, "\nLong quote:\n%s\n", quotebuf); */
  427. X        strcpy(quotebuf, "");
  428. X        } else {
  429. X        strcat(quotebuf, line);
  430. X        strcat(quotebuf, "\001");
  431. X        }
  432. X    }
  433. X    }
  434. X    printf("MAX\t%d\n", numq);
  435. X}
  436. END_OF_FILE
  437. if test 878 -ne `wc -c <'quotedb.c'`; then
  438.     echo shar: \"'quotedb.c'\" unpacked with wrong size!
  439. fi
  440. # end of 'quotedb.c'
  441. fi
  442. if test -f 'strfile.h' -a "${1}" != "-c" ; then 
  443.   echo shar: Will not clobber existing file \"'strfile.h'\"
  444. else
  445. echo shar: Extracting \"'strfile.h'\" \(627 characters\)
  446. sed "s/^X//" >'strfile.h' <<'END_OF_FILE'
  447. X/* @(#)strfile.h    1.2 (Berkeley) 5/14/81 */
  448. X# ifndef    __STRFILE__
  449. X
  450. X# define    __STRFILE__
  451. X
  452. X# include    <sys/types.h>
  453. X
  454. X# define    MAXDELIMS    3
  455. X
  456. X/*
  457. X * bits for flag field
  458. X */
  459. X
  460. X# define    STR_RANDOM    0x1
  461. X# define    STR_ORDERED    0x2
  462. X
  463. Xtypedef struct {        /* information table */
  464. X    unsigned long    str_numstr;        /* # of strings in the file */
  465. X    unsigned long    str_longlen;        /* length of longest string */
  466. X    unsigned long    str_shortlen;        /* length of shortest string */
  467. X    long        str_delims[MAXDELIMS];    /* delimiter markings */
  468. X    off_t        str_dpos[MAXDELIMS];    /* delimiter positions */
  469. X    short        str_flags;        /* bit field for flags */
  470. X} STRFILE;
  471. X
  472. X# endif        __STRFILE__
  473. END_OF_FILE
  474. if test 627 -ne `wc -c <'strfile.h'`; then
  475.     echo shar: \"'strfile.h'\" unpacked with wrong size!
  476. fi
  477. # end of 'strfile.h'
  478. fi
  479. if test -f 'unstr.c' -a "${1}" != "-c" ; then 
  480.   echo shar: Will not clobber existing file \"'unstr.c'\"
  481. else
  482. echo shar: Extracting \"'unstr.c'\" \(3701 characters\)
  483. sed "s/^X//" >'unstr.c' <<'END_OF_FILE'
  484. X# include    <stdio.h>
  485. X# include    <ctype.h>
  486. X# include    "strfile.h"
  487. X
  488. X# define    TRUE    1
  489. X# define    FALSE    0
  490. X
  491. X/*
  492. X *    This program un-does what "strfile" makes, thereby obtaining the
  493. X * original file again.  This can be invoked with the name of the output
  494. X * file, the input file, or both. If invoked with only a single argument
  495. X * ending in ".dat", it is pressumed to be the input file and the output
  496. X * file will be the same stripped of the ".dat".  If the single argument
  497. X * doesn't end in ".dat", then it is presumed to be the output file, and
  498. X * the input file is that name prepended by a ".dat".  If both are given
  499. X * they are treated literally as the input and output files.
  500. X *
  501. X *    Ken Arnold        Aug 13, 1978
  502. X */
  503. X
  504. X# define    DELIM_CH    '-'
  505. X
  506. Xchar    Infile[100],            /* name of input file */
  507. X    Outfile[100],            /* name of output file */
  508. X    Delimch = '%';            /* delimiter character */
  509. X
  510. Xshort    Oflag = FALSE;            /* use order of initial table */
  511. X
  512. XFILE    *Inf, *Outf;
  513. X
  514. Xchar    *rindex(), *malloc(), *strcat(), *strcpy();
  515. X
  516. Xmain(ac, av)
  517. Xint    ac;
  518. Xchar    **av;
  519. X{
  520. X    register int    c;
  521. X    register int    nstr, delim;
  522. X    static STRFILE    tbl;        /* description table */
  523. X
  524. X    getargs(ac, av);
  525. X    if ((Inf = fopen(Infile, "r")) == NULL) {
  526. X        perror(Infile);
  527. X        exit(-1);
  528. X        /* NOTREACHED */
  529. X    }
  530. X    if ((Outf = fopen(Outfile, "w")) == NULL) {
  531. X        perror(Outfile);
  532. X        exit(-1);
  533. X        /* NOTREACHED */
  534. X    }
  535. X    (void) fread((char *) &tbl, sizeof tbl, 1, Inf);
  536. X    if (Oflag) {
  537. X        order_unstr(&tbl);
  538. X        exit(0);
  539. X        /* NOTREACHED */
  540. X    }
  541. X    nstr = tbl.str_numstr;
  542. X    (void) fseek(Inf, (off_t) (sizeof (off_t) * (nstr + 1)), 1);
  543. X    delim = 0;
  544. X    nstr = 0;
  545. X    while ((c = getc(Inf)) != EOF)
  546. X        if (c != '\0')
  547. X            putc(c, Outf);
  548. X        else if (nstr != tbl.str_numstr - 1)
  549. X            if (++nstr == tbl.str_delims[delim]) {
  550. X                fprintf(Outf, "%c-\n", Delimch);
  551. X                delim++;
  552. X            }
  553. X            else
  554. X                fprintf(Outf, "%c%c\n", Delimch, Delimch);
  555. X    exit(0);
  556. X    /* NOTREACHED */
  557. X}
  558. X
  559. Xgetargs(ac, av)
  560. Xregister int    ac;
  561. Xregister char    *av[];
  562. X{
  563. X    register int    i;
  564. X    register char    *sp;
  565. X    register int    j;
  566. X    register short    bad;
  567. X
  568. X    bad = 0;
  569. X    for (i = 1; i < ac; i++)  {
  570. X        if (av[i][0] != '-') {
  571. X            (void) strcpy(Infile, av[i]);
  572. X            if (i + 1 >= ac) {
  573. X                (void) strcpy(Outfile, Infile);
  574. X                if ((sp = rindex(av[i], '.')) &&
  575. X                    strcmp(sp, ".dat") == 0)
  576. X                    Outfile[strlen(Outfile) - 4] = '\0';
  577. X                else
  578. X                    (void) strcat(Infile, ".dat");
  579. X            }
  580. X            else
  581. X                (void) strcpy(Outfile, av[i + 1]);
  582. X            break;
  583. X        }
  584. X        else if (av[i][1] == '\0') {
  585. X            printf("usage: unstr [-o] [-cC] datafile[.dat] [outfile]\n");
  586. X            exit(0);
  587. X            /* NOTREACHED */
  588. X        }
  589. X        else
  590. X            for (sp = &av[i][1]; *sp != '\0'; sp++)
  591. X                switch (*sp) {
  592. X                  case 'o':    /* print out in seekptr order */
  593. X                    Oflag++;
  594. X                    break;
  595. X                  case 'c': /* new delimiting char */
  596. X                    if ((Delimch = *++sp) == '\0') {
  597. X                        --sp;
  598. X                        Delimch = *av[++i];
  599. X                    }
  600. X                    if (!isascii(Delimch)) {
  601. X                        fprintf(stderr,
  602. X                            "bad delimiting character: 0x%x\n",
  603. X                            Delimch);
  604. X                        bad++;
  605. X                    }
  606. X                    break;
  607. X                  default:
  608. X                    fprintf(stderr, "unknown flag: '%c'\n",
  609. X                        *sp);
  610. X                    bad++;
  611. X                    break;
  612. X                }
  613. X    }
  614. X    if (bad) {
  615. X        printf("use \"%s -\" to get usage\n", av[0]);
  616. X        exit(-1);
  617. X    }
  618. X}
  619. X
  620. Xorder_unstr(tbl)
  621. XSTRFILE    *tbl;
  622. X{
  623. X    register int    i, c;
  624. X    register int    delim;
  625. X    register off_t    *seekpts;
  626. X
  627. X    seekpts = (off_t *) malloc(sizeof *seekpts * tbl->str_numstr);    /* NOSTRICT */
  628. X    if (seekpts == NULL) {
  629. X        perror("malloc");
  630. X        exit(-1);
  631. X        /* NOTREACHED */
  632. X    }
  633. X    (void) fread((char *) seekpts, sizeof *seekpts, (int) tbl->str_numstr,
  634. X             Inf);
  635. X    delim = 0;
  636. X    for (i = 0; i < tbl->str_numstr; i++, seekpts++) {
  637. X        if (i != 0)
  638. X            if (i == tbl->str_delims[delim]) {
  639. X                fputs("%-\n", Outf);
  640. X                delim++;
  641. X            }
  642. X            else
  643. X                fputs("%%\n", Outf);
  644. X        (void) fseek(Inf, *seekpts, 0);
  645. X        while ((c = getc(Inf)) != '\0')
  646. X            putc(c, Outf);
  647. X    }
  648. X}
  649. END_OF_FILE
  650. if test 3701 -ne `wc -c <'unstr.c'`; then
  651.     echo shar: \"'unstr.c'\" unpacked with wrong size!
  652. fi
  653. # end of 'unstr.c'
  654. fi
  655. echo shar: End of archive 1 \(of 1\).
  656. cp /dev/null ark1isdone
  657. MISSING=""
  658. for I in 1 ; do
  659.     if test ! -f ark${I}isdone ; then
  660.     MISSING="${MISSING} ${I}"
  661.     fi
  662. done
  663. if test "${MISSING}" = "" ; then
  664.     echo You have the archive.
  665.     rm -f ark[1-9]isdone
  666. else
  667.     echo You still need to unpack the following archives:
  668.     echo "        " ${MISSING}
  669. fi
  670. ##  End of shell archive.
  671. exit 0
  672. -- 
  673. Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
  674.